//------------------------------------------------------------------------------
// <copyright file="HeroDataAccess.cs" company="Damian Antonowicz">
//       copyright © 2010 Damian Antonowicz
// </copyright>
// <author>Damian Antonowicz</author>
// <email>poczta@damianantonowicz.pl</email>
//------------------------------------------------------------------------------

using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using DotBeer.Business.Entities;
using DAnton.Utilities.Helpers;
using System.Collections.Generic;
using DAnton.Utilities.Extensions;
using System.Diagnostics;
using System.Xml.Schema;
using System.Reflection;

namespace DotBeer.Data
{
    public class HeroDataAccess : AbstractDataAccess<Hero>
    {
        #region private members

        string heroName = String.Empty;
        string authorName = String.Empty;

        #endregion

        #region constructors

        public HeroDataAccess()
        {
            this.cacheData = false;
        }

        #endregion

        #region private methods

        protected override string GetSchemaPath()
        {
            return "DotBeer.Data.Schemas.HeroBuildSchema.xsd";
        }

        protected override string GetFilePath(params object[] list)
        {
            //save
            if (list.Length == 1 &&
                list[0] is Hero)
            {
                Hero hero = (Hero)list[0];
                this.heroName = hero.Name;
                this.authorName = hero.Author;
            }
            //load when heroName is provided
            else if (list.Length == 1 &&
                     list[0] is string)
            {
                this.heroName = list[0].ToString();
                this.authorName = this.GetAuthors(heroName).Take(1).SingleOrDefault();
            }
            //load when heroName and authorName is provided
            else if (list.Length == 2 &&
                     list[0] is string &&
                     list[1] is string)
            {
                this.heroName = list[0].ToString();
                this.authorName = list[1].ToString();
            }

            return String.Format(@"{0}\Heroes\{1} by {2}.xml", IOHelper.ApplicationStartupPath, heroName, authorName);
        }

        protected override void BeforeSave(Hero hero)
        {
            RequiredFolders.CreateHeroesDirectories();
            hero.LastUpdateDate = DateTime.Now;
        }

        protected override void AfterSave(Hero hero)
        {
            this.SetAuthors(hero.Name);
        }

        protected override void BeforeLoad()
        {
            this.SetAuthors(this.heroName);
        }

        protected override void AfterLoad(Hero hero)
        {
            ItemsCollectionDataAccess itemsCollDAL = new ItemsCollectionDataAccess();
            ItemsCollection itemsColl = itemsCollDAL.Load();

            foreach (ItemBuild build in hero.ItemBuilds)
            {
                foreach (ItemHero itemHero in build.Items)
                {
                    itemHero.ItemsCollection = itemsColl;

                    if (itemHero.Name.EndsWith(" "))
                        itemHero.Name = itemHero.Name.Remove(itemHero.Name.LastIndexOf(" "));
                }
            }

            HeroesCollectionDataAccess heroesCollectionDAL = new HeroesCollectionDataAccess();
            hero.Side = heroesCollectionDAL.Load().Heroes.Single(h => h.Name == hero.Name).Side;
        }

        private void SetAuthors(string heroName)
        {
            Authors authors = Authors.Instance;
            authors.Clear();
            authors.AddRange(this.GetAuthors(heroName));
        }

        private IEnumerable<string> GetAuthors(string heroName)
        {
            string dirPath = Path.Combine(IOHelper.ApplicationStartupPath, "Heroes");
            string pattern = String.Format(@"^{0}\sby\s(?<Author>.+)", heroName);
            //Aggron Stonebreaker, the Ogre Magi by kalorful

            if (Directory.Exists(dirPath))
            {
                foreach (FileInfo fi in new DirectoryInfo(dirPath).GetFiles())
                {
                    string fileName = Path.GetFileNameWithoutExtension(fi.Name);

                    if (Regex.IsMatch(fileName, pattern))
                    {
                        Match m = Regex.Match(fileName, pattern);
                        string authorName = m.Groups["Author"].Value;
                        yield return authorName;
                    }
                }
            }
        }

        #endregion
    }
}
